package com.android.task4;

public class BoundingBox extends Object {
	protected final int mLatNorthE6;
	protected final int mLatSouthE6;
	protected final int mLonEastE6;
	protected final int mLonWestE6;

	public BoundingBox(final int northE6, final int eastE6, final int southE6,
			final int westE6) {
		this.mLatNorthE6 = northE6;
		this.mLatSouthE6 = southE6;
		this.mLonWestE6 = westE6;
		this.mLonEastE6 = eastE6;
	}

	public BoundingBox(final double north, final double east,
			final double south, final double west) {
		this.mLatNorthE6 = (int) (north * 1E6);
		this.mLatSouthE6 = (int) (south * 1E6);
		this.mLonWestE6 = (int) (west * 1E6);
		this.mLonEastE6 = (int) (east * 1E6);
	}

	@Override
	public String toString() {
		return "BoundingBox[mLatNorthE6=" + this.mLatNorthE6 + ";mLonWestE6="
				+ this.mLonWestE6 + " -> mLatSouthE6=" + this.mLatSouthE6
				+ ";mLonEastE6=" + this.mLonEastE6 + "]";
	}

	public int getLatitudeSpanE6() {
		return Math.abs(this.mLatNorthE6 - this.mLatSouthE6);
	}

	public int getLongitudeSpanE6() {
		return Math.abs(this.mLonEastE6 - this.mLonWestE6);
	}

	public float[] getRelativePositionOfGeoPointInBoundingBoxWithLinearInterpolation(
			final int lat, final int lon) {
		float[] out = new float[2];
		out[MapTile.LATITUDE_INDEX] = ((float) (this.mLatNorthE6 - lat) / getLatitudeSpanE6());
		out[MapTile.LONGITUDE_INDEX] = 1 - ((float) (this.mLonEastE6 - lon) / getLongitudeSpanE6());
		return out;
	}

	public GeoPoint getGeoPointOfRelativePositionWithLinearInterpolation(
			final float relX, final float relY) {

		int lat = (int) (this.mLatNorthE6 - (this.getLatitudeSpanE6() * relY));
		int lon = (int) (this.mLonWestE6 + (this.getLongitudeSpanE6() * relX));

		lat = (int) Projection.Clip(lat,
				(int) (1E6 * MercatorProjection.MIN_LATITUDE),
				(int) (1E6 * MercatorProjection.MAX_LATITUDE));

		lon = (int) Projection.Clip(lon,
				(int) (1E6 * MercatorProjection.MIN_LONGITUDE),
				(int) (1E6 * MercatorProjection.MAX_LONGITUDE));

		return new GeoPoint(lat, lon);
	}

	public static BoundingBox getBoundingBoxFromMapTile(final Point mapTile,
			final int zoom, final TileSource tileSource) {
		final int y = mapTile.getY();
		final int x = mapTile.getX();
		final Point mapTile2 = new Point(y + 1, x + 1);

		final Coordinates mapCoords = tileSource.pointToCoordinates(mapTile,
				zoom);
		final Coordinates mapCoords2 = tileSource.pointToCoordinates(mapTile2,
				zoom);

		return new BoundingBox(mapCoords.getLatitude(), mapCoords2
				.getLongitude(), mapCoords2.getLatitude(), mapCoords
				.getLongitude());
	}
}